package com.caocaog.market.pay;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.caocaog.market.entity.*;
import com.caocaog.market.pay.vo.PayOrderVo;
import com.caocaog.market.pay.vo.RefundOrderVo;
import com.caocaog.market.pay.wxpay.WxPaySDX;
import com.caocaog.market.service.*;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.WxPayKit;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Map;

/**
 * @Description: UnionPay
 * @author: Yuki Guo
 * @date: 2021年11月01日 11:14
 */

@Slf4j
@Component
@EnableScheduling
public class UnionPaySDX {

    @Autowired
    private WxPaySDX wxPaySDX;
    @Autowired
    private IOrderRefundService orderRefundService;
    @Autowired
    private IOrderPayService orderPayService;
    @Autowired
    private IOrderBaseService orderBaseService;
    @Autowired
    private IOrderLineService orderLineService;
    @Autowired
    private GoodsHisService goodsHisService;
    @Autowired
    private IGoodsBasicService goodsBasicService;
    @Autowired
    private GoodsSpecService goodsSpecificationsService;
    @Autowired
    private IOrderStatusInfoService orderStatusInfoService;


    /**
     * 统一支付
     *
     * @param orderId      订单ID
     * @param //payType    支付类型 1微信 2支付宝
     * @param //wechatType 微信支付类型 1app 2小程序
     * @param //price      价格
     * @param nofity       回调地址          填写notify/{需要填写} 里面的
     * @param body         支付标题
     * @param attach       支付额外参数
     * @param openId       小程序openid
     * @return
     */


    @Transactional
    public Result<?> pay(String orderId, String nofity, String body,
                         String attach, String openId) {

        OrderBase orderBase = orderBaseService.getById(orderId);
        OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderId).orderByDesc("create_time").last(" limit 1 "));
        Result<?> result = null;
        //支付参数
        PayOrderVo vo = new PayOrderVo();

        vo.setBody(body);
        vo.setAttach(attach);
        vo.setTotalPrice(new BigDecimal(orderPay.getPayAmount()));
        vo.setNotifyUrl(nofity + "/wx");
        vo.setPayType("1");
        vo.setOutTradeNo("P" + orderBase.getOrderNo());//todo 订单支付记录id
        vo.setWechatType(2);
        vo.setOpenId(openId);
        System.out.printf("保磊兄的奶粉钱有了 +" + vo.getTotalPrice());
        //update orderPay
        orderPay.setPaySerno(vo.getOutTradeNo());
        orderPayService.updateById(orderPay);
        result = wxPaySDX.appPay(vo);

       /* if ("1".equals(payType)) {

            //微信
            result = wxPay.appPay(vo);

        } else if ("2".equals(payType)) {
            //支付宝
            result = aliPay.appPay(vo);
        } else {
            return Result.error("支付类型错误");
        }*/

        return result;
    }

//微信订单退款

    /**
     * 申请退款
     * Parameters:
     * orderId - orderId
     * orderNo - orderNo
     * refundNo - refundNo
     * refundAmount - refundAmount
     * Returns:
     * String 请求返回的结果
     *
     * @return
     */
    public Result<?> refund(String refundId, String outTradeNo) {
        OrderRefund orderRefund = orderRefundService.getById(refundId);

        RefundOrderVo vo = new RefundOrderVo();
        vo.setCause(orderRefund.getCause());
        vo.setOrderId(orderRefund.getOrderId());
        vo.setOrderNo(orderRefund.getOrderNo());
        vo.setRefundAmount(orderRefund.getRefundAmount());
        vo.setOutRefundNo("P" + orderRefund.getRefundNo());
        vo.setOutTradeNo(outTradeNo);
        vo.setNotifyUrl("/wxRefund");
        //update orderRefund
        orderRefund.setPayRefundSerno(vo.getOutRefundNo());
        orderRefundService.updateById(orderRefund);

        return wxPaySDX.refund(vo);

    }

    /**
     * 微信回调统一处理
     */
    @Transactional
    public Result<?> wxNotify() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        String xmlMsg = HttpKit.readData(request);
        log.info("------xmlMsg: " + xmlMsg);
        Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
        String returnCode = params.get("return_code");
        log.info("------returnCode: " + returnCode);
        // 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
        // 注意此处签名方式需与统一下单的签名类型一致
        if (WxPayKit.verifyNotify(params, wxPaySDX.getApiConfig().getPartnerKey(), SignType.HMACSHA256)) {
            if (WxPayKit.codeIsOk(returnCode)) {
                // 更新订单信息
                String attach = params.get("attach");
                //订单编号
                String out_trade_no = params.get("out_trade_no");
                log.info("------attach: " + attach + " ------out_trade_no: " + out_trade_no);
                OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("pay_serno", out_trade_no));

                if (null != orderPay && orderPay.getPayStatus() == 0) {
                    // 填入支付成功信息
                    //更新订单信息
                    orderPay.setEndPayInfo(params.toString());
                    orderPay.setPayStatus(1);//支付成功
                    orderPayService.updateById(orderPay);
                    OrderBase orderBase = orderBaseService.getById(orderPay.getOrderId());
                    orderBase.setStatus("1");
                    orderBaseService.updateById(orderBase);

//                    orderPayService.savePayEndInfo(out_trade_no,params.toString());
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("payNo", out_trade_no);
                    jsonObject.put("attach", attach);
                    log.info("------jsonObject: " + jsonObject);
                    return Result.OK(jsonObject);
                }
            }
        }
        return Result.error("-----error:" + params.toString());
    }

    /**
     * 微信回调统一处理
     */
    @Transactional
    public Result<?> wxRefundNotify() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        String xmlMsg = HttpKit.readData(request);
        log.info("------xmlMsg: " + xmlMsg);
        Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
        String returnCode = params.get("return_code");
        log.info("------returnCode: " + returnCode);

        return Result.OK();
    }


    //取消订单 每15分钟
   /* @Scheduled(cron = "0 0/15 * * * ?")
    public void cancelOrder() {

        String now = DateUtils.now();
        int num = 0;
        log.info("----------------执行取消订单" + now + ":开始------------------");
        List<OrderBase> orderBaseList = orderBaseService.list(new QueryWrapper<OrderBase>().eq("status", 0));
        for (OrderBase orderBase : orderBaseList) {
            OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderBase.getId()));
            if (oConvertUtils.isNotEmpty(orderPay) && orderPay.getPayStatus() == 0) {
                Calendar calSrc = Calendar.getInstance();
                calSrc.setTime(orderPay.getCreateTime());
                Calendar calDes = Calendar.getInstance();
                calDes.setTime(new Date());
                if (DateUtils.dateDiff('m', calDes, calSrc) >= 15) {
                    log.info("----------------取消订单-" + orderBase.getOrderNo() + "-" + orderBase.getStatus() + "------------------");
                    List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", orderBase.getId()));
                    for (OrderLine line : orderLineList) {
                        GoodsHis goodsHis = goodsHisService.getById(line.getGoodsHisId());
                        GoodsBasic goodsBasic = goodsBasicService.getById(goodsHis.getGoodsId());
                        if (!line.getSpecHisId().isEmpty()) {
                            GoodsSpecifications goodsSpecifications = goodsSpecificationsService.getById(line.getSpecHisId());
                            goodsSpecifications.setStock(goodsSpecifications.getStock() + line.getQuantity());//回滚库存
                            goodsSpecificationsService.updateById(goodsSpecifications);
                        }
                        goodsBasic.setSaleNum(goodsBasic.getSaleNum() - line.getQuantity());//回滚销量
                        goodsBasicService.updateById(goodsBasic);
                    }
                    orderPay.setPayStatus(2);//支付失败 订单取消
                    orderPay.setEndPayInfo("订单15分钟内未支付,已取消");
                    orderPayService.updateById(orderPay);
                    orderBase.setStatus("-1");//订单取消
                    orderBaseService.updateById(orderBase);
                    num += 1;
                    //添加状态记录
                    OrderStatusInfo orderStatusInfo = OrderStatusInfo.builder().orderId(orderBase.getId())
                            .orderNo(orderBase.getOrderNo()).orderStatusName("订单已取消").createBy("系统自动取消")
                            .createTime(new Date()).remark("").build();
                    orderStatusInfoService.save(orderStatusInfo);
                    log.info("----------------取消订单-" + orderBase.getOrderNo() + "-成功------------------");
                }
            }
        }
        log.info("----------------执行取消订单-" + now + "-取消订单个数-" + num + " :结束------------------");

    }*/

    /**
     * 支付宝回调统一处理
     */
   /* @Transactional
    public Result<?> aliNotify() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        try {
            // 获取支付宝POST过来反馈信息
            Map<String, String> params = AliPayApi.toMap(request);
            for (Map.Entry<String, String> entry : params.entrySet()) {
                System.out.println(entry.getKey() + " = " + entry.getValue());
            }
            boolean verifyResult = AlipaySignature.rsaCheckV1(params, aliPayBean.getAliPayPublicKey(), "UTF-8", "RSA2");
            if (verifyResult) {
                System.out.println("进来了");
                // 更新订单信息
                String passbackParams = params.get("passback_params");
                //订单编号
                String payInfoId = params.get("out_trade_no");
                boolean isPay = orderPayInfoService.selectIsPay(payInfoId);
                if (!isPay) {
                    //填入支付成功信息
                    System.out.println("进入判断------------------------");
                    orderPayInfoService.savePayEndInfo(payInfoId, params.toString());
                    System.out.println("成功了吗");
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("payInfoId", payInfoId);
                    jsonObject.put("attach", passbackParams);
                    return Result.OK(jsonObject);
                }
            } else {
                System.out.println("certNotifyUrl 验证失败");
                return Result.error("error");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return Result.error("error");
        }
        return Result.error("error");
    }
*/
}

